/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mb.webserver.console;

import mb.webserver.handler.MbServerConfig;
import mb.webserver.handler.BranchData;
import mb.webserver.handler.CompaniesData;
import mb.webserver.handler.ServiceDetail;
import mb.webserver.handler.HomePage;
import mb.webserver.handler.PromotionData;
import mb.webserver.handler.NewsData;
import mb.webserver.handler.ATMData;
import mb.webserver.handler.ListFunction;
import mb.webserver.handler.ServiceData;
import java.util.Properties;
import mb.config.Constants;
import mb.config.WebserverConfig;
import mb.webserver.handler.QueryTopATM;
import mb.webserver.handler.QueryTopBranch;
import mb.webserver.handler.QueryTopCategory;
import mb.webserver.handler.StockData;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.thread.QueuedThreadPool;

/**
 *
 * @author thanh.nguyenchi
 */
public class MBWebServer extends Thread {
    
    private final SelectChannelConnector httpConnector = new SelectChannelConnector();
    private ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
    private final Server server = new Server();      
    private int port;
    private int maxIdleTime;
    private int headerSize;
    private int maxThread;
    private int minThread;
    
    public MBWebServer(WebserverConfig objConfig){
        this.setName(Constants.STR_WEBSERVER_THREAD);
        this.port = objConfig.getPort();
        this.maxIdleTime = objConfig.getMaxIdleTime();
        this.headerSize = objConfig.getHeaderSize();
        this.maxThread = objConfig.getMaxThread();
        this.minThread = objConfig.getMinThead();
        try{
            setConfig();
            initWebserver();
            addServlet();
        }
        catch(Exception ex){            
        }
    }
    
    public void run() {
        startWebserver();
    }
    
    public void stopWebserver(){
        try {
            server.stop();  
            
            // sleep 3s for release resource
            Thread.currentThread().sleep(3000);
        } catch(Exception e) {
            System.out.println("webServer stop [err]:" + e.toString());
            return;
        }    
    }
    
    public void startWebserver(){
        //System.out.println("Starting webserver...");
        try {
            server.start();
            server.join();
        } catch(Exception e) {
            System.out.println("webServer start [err]:" + e.toString());
            return;
        }
    }
    
    public void setConfig(){        
        org.eclipse.jetty.util.log.Log.setLog(new NoLogging());
    }
    
    public void initWebserver(){
        
        httpConnector.setPort(this.port);        
        httpConnector.setMaxIdleTime(this.maxIdleTime);
        httpConnector.setRequestHeaderSize(this.headerSize);         
        QueuedThreadPool threadPool = new QueuedThreadPool();
        threadPool.setMaxThreads(this.maxThread);
        threadPool.setMinThreads(this.minThread);       
        httpConnector.setThreadPool(threadPool);  
        context.setErrorHandler(createErrorHandler());
        context.setContextPath("/");
        context.setResourceBase(Constants.STR_WEBSERVER_ROOT);
        context.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed", "false");
        context.setClassLoader(Thread.currentThread().getContextClassLoader());
        context.addServlet(DefaultServlet.class, "/");       
    }
    
    private ErrorHandler createErrorHandler() {
        ErrorPageErrorHandler errorHandler = new ErrorPageErrorHandler();
        errorHandler.addErrorPage(404, "/error.html");
        return errorHandler;
    }

    
    public void addServlet(){
        // home
        context.addServlet(new ServletHolder(new HomePage()),"/home");
        // servlet mbconfig
        context.addServlet(new ServletHolder(new MbServerConfig()),"/api/loadConfig");
        context.addServlet(new ServletHolder(new ListFunction()),"/api/loadFunction");
        context.addServlet(new ServletHolder(new ATMData()),"/api/loadATMData");
        context.addServlet(new ServletHolder(new BranchData()),"/api/loadBranchData");
        context.addServlet(new ServletHolder(new PromotionData()),"/api/loadPromotionData");
        context.addServlet(new ServletHolder(new ServiceData()),"/api/loadServieData");
        context.addServlet(new ServletHolder(new ServiceDetail()),"/api/loadServieDetail");
        context.addServlet(new ServletHolder(new CompaniesData()),"/api/loadCompaniesData");
        context.addServlet(new ServletHolder(new NewsData()),"/api/loadListNewsData");
        context.addServlet(new ServletHolder(new StockData()),"/api/loadStockData");
        
        // servlet query
        context.addServlet(new ServletHolder(new QueryTopATM()),"/api/queryTopAtm");
        context.addServlet(new ServletHolder(new QueryTopBranch()),"/api/queryTopBranch");
        context.addServlet(new ServletHolder(new QueryTopCategory()),"/api/queryTopCategory");
                
        // set Hanlder
        server.setConnectors(new Connector[]{ httpConnector});        
        server.setHandler(context);        
    }   
}
